var conquest = conquest || {};
conquest.util = conquest.util || {};

(function(util) {
	util.toJSON = function(data) {
		var json;
		if ($.isArray(data)) {
			json = [];
			_.each(data, function(inputItem) {
				json.push(inputItem.toJSON());
			});
		} else {
			json = data.toJSON();
		}
		return json;
	};

	util.membersGroupBy = function(data, groupKey, sortKey, groupFactory) {
		var members;
		if (data instanceof Backbone.Collection) {
			members = data.models;
		} else {
			members = data;
		}

		members = members.filter(function(member) {
			return member.get('quantity') > 0;
		});

		if (sortKey) {
			members = this.membersSortBy(members, sortKey);
		}

		var membersHash = _.groupBy(members, function(member) {
			if (groupKey == 'memberQuantity') {
				return member.get('quantity');
			} else {
				return member.get('card')[groupKey];
			}
		});

		var defaultGroupFactory = function(key, members) {
			return {
				title: groupKey == 'memberQuantity' ? key + 'x' : key,
				members: conquest.util.toJSON(members),
				quantity: _.reduce(members, function(totalQuantity, member) {
					return totalQuantity + member.get('quantity');
				}, 0)

			};
		};
		
		var groups = [];
		_.each(Object.keys(membersHash), function(key) {
			groups.push((groupFactory || defaultGroupFactory)(key, membersHash[key]));
		});
		groups = groups.sort(function(one, two) {
			return one.title.localeCompare(two.title);
		});

		return groups;
	};

	util.membersSortBy = function(input, key) {
		var members;
		if (input instanceof Backbone.Collection) {
			members = input.models;
		} else {
			members = input;
		}

		var keys;
		if (_.isArray(key)) {
			keys = key;
		} else {
			keys = [ key ];
		}
		keys.push('name');

		var stringKeys = ['name', 'type', 'typeDisplay', 'faction', 'factionDisplay'];
		var numberKeys = ['memberQuantity', 'quantity', 'cost', 'shield', 'comamnd', 'attack', 'hitPoints'];

		var sorter = function(one, two) {
			var result = 0;
			$.each(keys, function(index, key) {
				var property;
				var descending;
				if (_.isObject(key)) {
					property = key.property;
					descending = key.descending;
				} else {
					property = key;
					descending = false;
				}
				var oneValue;
				var twoValue;
				if (property == 'memberQuantity') {
					oneValue = one.get('quantity');
					twoValue = two.get('quantity');
				} else {
					oneValue = one.get('card')[property];
					twoValue = two.get('card')[property];
				}

				if (stringKeys.indexOf(property) > -1) {
					result = oneValue.localeCompare(twoValue);
				} else if (numberKeys.indexOf(property) > -1) {					
					result = (oneValue == twoValue ? 0 : (oneValue < twoValue ? -1 : 1));
				}

				if (result != 0) {
					if (descending === true) {
						result *= -1;
					}
					return false;
				}
			});

			return result;
		};

		return members.sort(sorter);
	};

	util.toCardUrl = function(input) {
		return '/' + conquest.static.language + '/card/' + util.toCardRelativeUrl(input);
	}

	util.toCardRelativeUrl = function(input) {
		var card;
		if (_.isNumber(input)) {
			card = conquest.dict.findCard(input);
		} else {
			card = input;
		}
		
		return (card.setNumber + "").leftPad(2, '0') + '-' + card.setTechName  
				+ '/' + (card.number + "").leftPad(3, '0') + '-' + card.techName;
	}

	util.toTechName = function(input) {
		return input.toLowerCase().replace(/[\']/g, '').replace(/[^a-z0-9]+/g, ' ').trim().replace(/\ +/g, '-');
	};

	util.toFactionImageBase = function(techName) {
		return conquest.static.imagePath + '/faction/' + techName;
	};

	util.toFactionImageMd = function(techName) {
		return util.toFactionImageBase(techName) + '-b-md.png';
	};

	util.toFactionImageLg = function(techName) {
		return util.toFactionImageBase(techName) + '-b.png';
	};

	util.toCardImage = function(imageBase) {
		return conquest.static.imagePath + '/card/' + imageBase + '.jpg';
	};

	util.writeAttr = function(name, value) {
		return name + '="' + value + '"';
	};

	util.writeAttrs = function(attrs) {
		var result = '';
		if (!_.isUndefined(attrs)) {
			for (var key in attrs) {
				result = result + ' ' + util.writeAttr(key, attrs[key]);
			}
		}
		return result.trim();
	};

	util.writeFactionImgElem = function(techName) {
		return '<img src="' + util.toFactionImageMd(techName) + '" />';
	};

	util.writeCardImgElem = function(imageBase, attrs) {
		return '<img ' + util.writeAttrs($.extend({
			src: util.toCardImage(imageBase)
		}, attrs)) + ' />';
	};
})(conquest.util);